﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Data.Common;
using MYLSOFT.JsonSimple;
using System.Data;

namespace com.byt.webcore.utils
{
    public static class Utils
    {

        public static string concatIf(string s1, string s2)
        {
            return string.IsNullOrEmpty(s1) || string.IsNullOrEmpty(s2) ? "" : s1 + s2;
        }

        public static string padLeft(string str, char car, int maxlength)
        {
            if (str == null)
                str = "";
            int falta = maxlength - str.Length;
            for (int i = 0; i < falta; i++)
            {
                str = car + str;
            }
            return str;
        }

        public static string padRight(string str, char car, int maxlength)
        {
            if (str == null)
                str = "";
            int falta = maxlength - str.Length;
            for (int i = 0; i < falta; i++)
            {
                str = str + car;
            }
            return str;
        }

        /*
            public static string resolveClientURL(ServletBase.Parameters p, string URL) {
                return resolveClientURL(p.req.getContextPath(), p.req.getRequestURI(), URL);
            }

            public static string resolveClientURL(string contextPath, string requestUri, string URL) {
                URL = URL.replaceFirst("~", contextPath);
                int minlen = Math.min(URL.Length, requestUri.Length);
                int c = 0;
                while ((c < minlen) && (URL.charAt(c) == requestUri.charAt(c)))
                    c++;
                URL = URL.substring(c);
                requestUri = requestUri.substring(c);
                if (requestUri.charAt(0) == '/')
                    requestUri = requestUri.substring(1);

                int count = 0;
                for (int i = 0; i < requestUri.Length; i++)
                    if (requestUri.charAt(i) == '/')
                        count++;
                requestUri = "";
                for (int i = 0; i < count; i++)
                    requestUri += "../";
                requestUri += URL;

                return requestUri;
            }
                * */

       public static string DecodeURIComponent(string encodedURI)
        {
            if (encodedURI == null || encodedURI.Length == 0)
            {
                return encodedURI;
            }
            char actualChar;

            StringBuilder buffer = new StringBuilder();

            int bytePattern, sumb = 0;

            for (int i = 0, more = -1; i < encodedURI.Length; i++)
            {
                actualChar = encodedURI[i];

                switch (actualChar)
                {
                    case '%':
                        {
                            actualChar = encodedURI[++i];
                            int hb =
                                (char.IsDigit(actualChar) ? actualChar - '0' : 10 + char.ToLower(actualChar) - 'a') &
                                0xF;
                            actualChar = encodedURI[++i];
                            int lb =
                                (char.IsDigit(actualChar) ? actualChar - '0' : 10 + char.ToLower(actualChar) - 'a') &
                                0xF;
                            bytePattern = (hb << 4) | lb;
                            break;
                        }
                    case '+':
                        {
                            bytePattern = '+';
                            break;
                        }
                    default:
                        {
                            bytePattern = actualChar;
                            break;
                        }
                }

                // Decode byte bytePattern as UTF-8, sumb collects incomplete chars

                if ((bytePattern & 0xc0) == 0x80)
                { // 10xxxxxx
                    sumb = (sumb << 6) | (bytePattern & 0x3f);
                    if (--more == 0)
                        buffer.Append((char)sumb);
                }
                else if ((bytePattern & 0x80) == 0x00)
                { // 0xxxxxxx
                    buffer.Append((char)bytePattern);
                }
                else if ((bytePattern & 0xe0) == 0xc0)
                { // 110xxxxx
                    sumb = bytePattern & 0x1f;
                    more = 1;
                }
                else if ((bytePattern & 0xf0) == 0xe0)
                { // 1110xxxx
                    sumb = bytePattern & 0x0f;
                    more = 2;
                }
                else if ((bytePattern & 0xf8) == 0xf0)
                { // 11110xxx
                    sumb = bytePattern & 0x07;
                    more = 3;
                }
                else if ((bytePattern & 0xfc) == 0xf8)
                { // 111110xx
                    sumb = bytePattern & 0x03;
                    more = 4;
                }
                else
                { // 1111110x
                    sumb = bytePattern & 0x01;
                    more = 5;
                }
            }
            return buffer.ToString();
        }


        public static string toUpperCase(string str)
        {
            if (string.IsNullOrEmpty(str))
                return str;
            return str.ToUpper();
        }


        public static string AsString(object str)
        {
            if (str == null)
                return "";
            return str.ToString().Trim();
        }

        public static DateTime? parseDate(string value)
        {
            try
            {
                return DateTime.ParseExact(value, "dd/MM/yyyy H:mm:ss", CultureInfo.InvariantCulture);
            }
            catch (Exception)
            {
                return null;
            }

        }

        public static string parseDate(DateTime value)
        {
            try
            {
                //return value.ToString("dd/MM/yyyy H:mm:ss");
                return value.ToString("dd/MM/yyyy");
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static int parseInteger(object value, int defaultValue)
        {
            try
            {
                return int.Parse(value.ToString());
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        public static int? parseInteger(object value)
        {
            try
            {
                return int.Parse(value.ToString());
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static double? parseBigDecimal(object value)
        {
            return parseDouble(value);
        }

        public static double? parseDouble(object value)
        {
            try
            {
                return double.Parse(value.ToString());
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static DateTime? getSqlDate(string fecha)
        {
            return parseDate(fecha);
        }

        public static string getSqlDate(DateTime fecha)
        {
            return parseDate(fecha);
        }

        /*
     public static string getSqlTimestamp(java.sql.Timestamp fecha) {
         if (fecha == null)
             return "";
         SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
         java.util.Date jDate = new java.util.Date(fecha.getTime());
         return format.format(jDate);
     }
        */

        public static string containsParse(string text)
        {
            if (text == null)
                return null;

            StringBuilder sb = new StringBuilder();
            string[] str = text.Split(' ');
            string s;
            for (int i = 0, len = str.Length; i < len; i++)
            {
                s = str[i].Trim().ToUpper();
                if (s.Length > 0)
                {

                    if ("DE".Equals(s))
                        continue;
                    if ("LA".Equals(s))
                        continue;
                    /*
                    if("Y".equals(s))
                        continue;
                    */

                    if (sb.Length > 0)
                        sb.Append(" AND ");
                    sb.Append("\"" + s + "%\"");
                }
            }

            return sb.ToString();
        }

        /*
     public static string callProcedure(string procedureName, int paramCount) {
         StringBuilder sb = new StringBuilder("{call " + procedureName + "(");
         for (int n = 1; n <= paramCount; n++) {
             sb.Append("?");
             if (n < paramCount)
                 sb.Append(",");
         }
         return sb.Append(")}").ToString();
     }

     public static void setParameter(PreparedStatement stmt, int index, int type, object value) throws Exception {
         try {
             if (value == null) {
                 stmt.setNull(index, type);
                 return;
             }
             switch (type) {
                 case Types.VARCHAR:
                     stmt.setString(index, value.ToString());
                     break;
                 case Types.INTEGER:
                     stmt.setInt(index, parseInteger(value));
                     break;
                 case Types.NUMERIC:
                     stmt.setBigDecimal(index, parseBigDecimal(value));
                     break;
                 case Types.DATE:
                     stmt.setDate(index, getSqlDate(value.ToString()));
                     break;
             }
         } catch (SQLException e) {
             throw e;
         } catch (NullPointerException e) {
             stmt.setNull(index, type);
         }
     }
        */

        public static object executeScalar(DbConnection conn, string sql, params object[] parametros)
        {
            try
            {
                DbCommand stmt = conn.CreateCommand();
                stmt.CommandText = string.Format(sql, parametros);
                object result = stmt.ExecuteScalar();
                return result;

            }
            catch (Exception e)
            {
                return null;
            }
        }

        public static int executeNonQuery(DbConnection conn, string sql, params object[] parametros)
        {
            DbCommand stmt = conn.CreateCommand();
            stmt.CommandText = string.Format(sql, parametros);

            int result = stmt.ExecuteNonQuery();
            return result;
        }

        public static DbDataReader executeResultSet(DbConnection conn, string sql, params object[] parametros)
        {
            try
            {
                DbCommand stmt = conn.CreateCommand();
                stmt.CommandText = string.Format(sql, parametros);
                DbDataReader rs = stmt.ExecuteReader();
                return rs;

            }
            catch (Exception e)
            {
                return null;
            }
        }

        public static string[] getColumns(DataTable meta)
        {

            // Construir el Nombre de las Columnas
            List<string> cl = new List<string>();
            string cname;

            //Para cada campo de la tabla...
            foreach (DataRow myField in meta.Rows)
            {
                //Para cada propiedad del campo...
                cname = myField[0].ToString();
                cl.Add(cname);
            }
            string[] cols = cl.ToArray();

            return cols;
        }

        /*
     public static JSONObject getJSONMatriz(DbDataReader rs)  {
         JSONObject jo = new JSONObject();

         DataTable meta = rs.getMetaData();
         int numcols = meta.getColumnCount();
         int sep;
         string[] cols = Utils.getColumns(meta);
         string id;

         // Crear la Cabecera
         JSONArray ja = new JSONArray();
         JSONArray jids = new JSONArray();
         for (int i = 0; i < numcols; i++) {
             JSONObject header = new JSONObject();

             sep = cols[i].indexOf("[[");
             if (sep > -1) {
                 id = "pvt" + cols[i].substring(0, sep);
                 header.put("header", cols[i].substring(sep + 2));
             } else {
                 id = cols[i];
                 header.put("header", cols[i]);
             }
             jids.add(id);
             header.put("dataIndex", id);
             header.put("width", 50);
             ja.add(header);
         }

         jo.put("header", ja);
         jo.put("store", jids);
         jo.put("data", getJSONArrayArray(rs));
         return jo;
     }
        */

        public static JSONObject getJSONObject(DbConnection conn, string sql, params object[] parametros)
        {
            sql = string.Format(sql, parametros);
            DbCommand stmt = conn.CreateCommand();
            stmt.CommandText = sql;
            DbDataReader rs = stmt.ExecuteReader();
            JSONObject json = getJSONObject(rs);
            return json;
        }

        /*
        public static object getObjectFromTable(int type, object value)
        {
            if (value != null)
            {
                switch (type)
                {
                    case Types.DATE:
                        value = Utils.getSqlDate((DateTime)value);
                        break;
                    case Types.TIMESTAMP:
                        value = Utils.getSqlTimestamp((TimeStamp)value);
                        break;
                    case -3: //2005
                        value = value.ToString();
                        break;
                }
            }
            else
            {
                value = "";
            }
            return value;
        }
        */

        public static JSONObject getJSONObject(DbDataReader rs)
        {
            DbJson dbj = new DbJson(rs);
            return dbj.ToObject();
        }

        public static JSONArray getJSONArrayObject(DbDataReader rs)
        {
            DbJson dbj = new DbJson(rs);
            return dbj.ToArrayObject();
        }

        public static JSONArray getJSONArrayArray(DbDataReader rs)
        {
            DbJson dbj = new DbJson(rs);
            return dbj.ToArrayArray();
        }

     static int inxId;
     static int inxText;
     static int inxParent;
     static int inxTag;
     static bool salir;
     
     private static void getSubTree(DbDataReader rs, StringBuilder sb, string parent) {


         rs.Read();
         string par = rs.GetString(inxParent);

         while (salir && parent.Equals(par))
         {
             //, \"checked\": false
             string filecss;
             filecss = rs.GetString(inxText);
             filecss = "tb-" + filecss.Substring(filecss.LastIndexOf(".") + 1).ToLower();
             sb.Append("{" + string.Format("\"idfile\":\"{0}\", \"file\":\"{1}\", \"fileobs\":\"{2}\", \"leaf\":true, \"iconCls\":\"{3}\" ", rs.GetString(inxId), rs.GetString(inxText), rs.GetString(inxTag), filecss ) + "},");
             salir = rs.Read();
             par = rs.GetString(inxParent);
         }
     }
        
     public static string getJSONTree(DbDataReader rs, int indexId, int indexText, int indexParent, 
                                      int indexTag)  {
         inxId = indexId;
         inxText = indexText;
         inxParent = indexParent;
         inxTag = indexTag;

         //StringBuilder sb = new StringBuilder("{\"arbolito\":");
         StringBuilder sb = new StringBuilder("{\"text\":\".\",\"children\":");
         sb.Append("[");
         salir = true;
         rs.Read();
         while (salir)
         {
             sb.Append("{" + string.Format("\"idfile\":\"{0}\", \"file\":\"{1}\", \"fileobs\":\"{2}\" ", rs.GetString(inxId), rs.GetString(inxText), rs.GetString(inxTag)));
             sb.Append(", \"children\":[");

                getSubTree(rs, sb, rs.GetString(inxParent));

             sb.Append("]},");

         }
         sb.Append("]");

         sb.Append("}");

         return sb.ToString();
     }

     public static string getJSONTree(DbDataReader rs)  {
         return getJSONTree(rs, 0, 1, 3, 2);
     }

     public static string getJSONTree(DbDataReader rsparent, DbDataReader rschild)
     {
         StringBuilder sb = new StringBuilder("{\"text\":\".\",\"children\":");
         sb.Append("[");
         while (rsparent.Read())
         {
             sb.Append("{" + string.Format("\"formato\":\"{0}\", \"id_solicitud\":\"{1}\", \"id_version\":\"{2}\", \"flujo\":\"{3}\", \"orden\":\"{4}\", \"suce\":\"{5}\", \"actividad\":\"{6}\", \"nombactividad\":\"{7}\", \"iconCls\":\"tb-folder1212\"", rsparent.GetString(0), rsparent.GetInt32(1), rsparent.GetInt32(2), rsparent.GetInt32(3), rsparent.GetString(4), rsparent.GetString(5), rsparent.GetString(6), rsparent.GetString(7)));
             sb.Append(", \"children\":[");

             while (rschild.Read())
             {
                 sb.Append("{" + string.Format("\"formato\":\"{0}\", \"id_solicitud\":\"{1}\", \"id_version\":\"{2}\", \"flujo\":\"{3}\", \"orden\":\"{4}\", \"suce\":\"{5}\", \"actividad\":\"{6}\", \"nombactividad\":\"{7}\", \"leaf\":true, \"iconCls\":\"tb-document\"", rschild.GetString(0), rschild.GetInt32(1), rschild.GetInt32(2), rschild.GetInt32(3), rschild.GetString(4), rschild.GetString(5), rschild.GetString(6), rschild.GetString(7)) + "},");
             }

             sb.Append("]}");
             
         }
         sb.Append("]");
         sb.Append("}");
         return sb.ToString();
     }


        public static string BytesToHex(byte[] bytes)
        {
            StringBuilder sb = new StringBuilder(bytes.Length * 2);

            foreach (byte b in bytes)
                sb.AppendFormat("{0:X2}", b);
            return sb.ToString();
        }

        public static byte[] HexToBytes(string str)
        {
            int nBytes = str.Length / 2;
            byte[] bytes = new byte[nBytes];
            for (int i = 0; i < nBytes; i++)
            {
                bytes[i] = byte.Parse(str.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
            }
            return bytes;
        }


    }
}
